﻿using System;
using System.Collections.Generic;
using System.Linq;
using StockholmsStad.Web.UI.Class.Interfaces;
using StockholmsStad.Web.UI.UIServiceReference;

namespace StockholmsStad.Web.UI.Class.Controller
{
    /// <summary>
    /// MVC Controller för bokningen
    /// </summary>
    public class BookingController
    {
        /// <summary>
        /// Modellen som kontrollern jobbar mot
        /// </summary>
        private readonly IBookingModel _bookingModel;

        private readonly IBokning3_Confirm _confirmView;

        private readonly ILoginModel _loginModel;

        /// <summary>
        /// Skapar Controller och dess vyer och modellen
        /// </summary>
        /// <param name="bookingModel"></param>
        /// <param name="loginModel"></param>
        /// <param name="confirmView"></param>
        public BookingController(IBookingModel bookingModel, ILoginModel loginModel, IBokning3_Confirm confirmView)
        {
            _confirmView = confirmView;
            _loginModel = loginModel;
            _bookingModel = bookingModel;
        }

        /// <summary>
        /// Svarar true om användaren är inloggad
        /// </summary>
        public bool IsLoggedIn
        {
            get { return _loginModel.IsLoggedIn; }
        }

        /// <summary>
        /// Alla lediga tider som går att boka för en vigsel i stadshuset. Frågan går inte ned till server,
        /// utan propertien måste sättas explicit.
        /// </summary>
        public IOrderedEnumerable<DateTime> CachedFreeTimeblocksOrdinary
        {
            get { return _bookingModel.CachedFreeTimeblocksOrdinary; }
        }

        /// <summary>
        /// Alla lediga tider som går att boka för en vigsel på annan plats. Frågan går inte ned till server,
        /// utan propertien måste sättas explicit.
        /// </summary>
        public IOrderedEnumerable<DateTime> CachedFreeTimeblocksIndividual
        {
            get { return _bookingModel.CachedFreeTimeblocksIndividual; }
        }
        
        /// <summary>
        /// Alla bokade dagar som går att sätta som önskat datum. Frågan går inte ned till server,
        /// utan propertien måste sättas explicit.
        /// </summary>
        public IEnumerable<DateTime> CachedBookedTimeblocks
        {
            get { return _bookingModel.CachedBookedTimeblocks; }
        }

        /// <summary>
        /// Hämtar nuvarande bokning
        /// </summary>
        public Booking Booking
        {
            get { return _bookingModel.Booking; }
        }

        /// <summary>
        /// Alla tillgängliga ceremonityper. Borde vara Stadshuset och Individuell
        /// </summary>
        public IList<ValueIdPair> CeremonyTypes
        {
            get { return _bookingModel.CeremonyTypes; }
        }

        /// <summary>
        /// Sparar tiderna temporärt
        /// </summary>
        /// <param name="bookingDateTime"></param>
        public void ChooseBookingTimes(Booking bookingDateTime)
        {
            bookingDateTime.BookingMadeBeforeLogin = !_loginModel.IsLoggedIn;
            _bookingModel.Booking = bookingDateTime;
            _confirmView.UpdateBooking(bookingDateTime,
                                       _bookingModel.GetLocationName((int) bookingDateTime.CeremonyType));
        }

        /// <summary>
        /// Beräftar att de sparade tiderna ska skickas till server
        /// </summary>
        public void SubmitBooking()
        {
            _bookingModel.RegisterBooking(_loginModel.User);
        }

        /// <summary>
        /// Returnerar true om bokningskoden matchas av en förrättare
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool IsBookingCodeValid(string text)
        {
            return _bookingModel.IsBookingCodeValid(_loginModel.User, text);
        }

        /// <summary>
        /// Sparar av nuvarande bokning till server
        /// </summary>
        public void RegisterBooking()
        {
            _bookingModel.RegisterBooking(_loginModel.User);
        }

        /// <summary>
        /// Initialiserar cachning av fria tider och upptagna dagar
        /// </summary>
        public void InitializeCachedTimeblocks()
        {
            _bookingModel.CachedFreeTimeblocksOrdinary =
                _bookingModel.GetFreeTimeblocks(_loginModel.User, true).Select(t => t.StartDateTime).OrderBy(d => d.Ticks);
            
            _bookingModel.CachedFreeTimeblocksIndividual =
                _bookingModel.GetFreeTimeblocks(_loginModel.User, false).Select(t => t.StartDateTime).OrderBy(d => d.Ticks);
            
            _bookingModel.CachedBookedTimeblocks =
                _bookingModel.GetBookedTimeblocks(_loginModel.User).Select(t => t.StartDateTime).OrderBy(d => d.Ticks);
        }
    }
}